package client;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

import event.Event;
import event.EventHandler;

public class ComServer implements Runnable {
	private Socket mSocket;

	private DataOutputStream mDos;
	private DataInputStream mDis;

	private String mDefaultTransferPath;

	private boolean mCancel = false;

	private final EventManager<Event, EventHandler> mEventManager;

	public ComServer(InetAddress ip, int port,
			EventManager<Event, EventHandler> eventManager) throws IOException {
		mSocket = new Socket(ip, port);

		mEventManager = eventManager;

		mDos = new DataOutputStream(mSocket.getOutputStream());
		mDis = new DataInputStream(mSocket.getInputStream());

		mDefaultTransferPath = new File("").getAbsolutePath();
	}

	public void search(String query) throws IOException {
		mDos.writeInt(Event.SEARCH_TYPE);
		mDos.writeLong(0);
		mDos.writeLong(0);
		mDos.writeInt(0);
		mDos.writeUTF(query + "DELIMETER" + InetAddress.getLocalHost().getHostAddress());

		Log.println("> searching for: \"" + query + "\"");
	}

	public void requestFileHost(String file) throws IOException {
		mDos.writeInt(Event.FIL_TYPE);
		mDos.writeLong(0);
		mDos.writeLong(0);
		mDos.writeInt(0);
		mDos.writeUTF(file);

		Log.println("> request download of: \"" + file + "\"");
	}

	public void sendAvailableFileList(File dir) {
		try {
			ServerDirectoryEventHandler.sendDirectoryList(dir, mDos);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		String input;
		try {
			Event e = null;
			byte[] buffer = null;

			String parameters;
			int response, len;
			long packageOffset, packageSize;

			while (!mCancel && mSocket.isConnected()) {
				// ------------------------------------------
				// This is the protocol for every message:
				// ------------------------------------------
				// (int) EVENT_TYPE
				// (long) OFFSET (offset of segment in TOTAL_LENGTH)
				// (long) TOTAL_LENGTH (total message length)
				// (int) SEGMENT_LENGTH (<= TOTAL_LENGTH)
				// (UTF) PARAMETER
				// (byte[]) BUFFER (of size SEGMENT_LENGTH)
				// ------------------------------------------

				response = mDis.readInt();
				packageOffset = mDis.readLong();
				packageSize = mDis.readLong();
				len = mDis.readInt();
				parameters = mDis.readUTF();

				if (len > 0) {
					buffer = new byte[len];
					mDis.readFully(buffer, 0, len);

					e = new Event(response, parameters, buffer, packageOffset,
							packageSize, mDos);
				} else {
					e = new Event(response, parameters, null, packageOffset,
							packageSize, mDos);
				}

				mEventManager.put(e);
			}
		} catch (IOException e) {
			e.printStackTrace();
			System.out.print("ERROR: communication with server failed.");
		} finally {

		}
	}

	public void cancel() {
		mCancel = true;
	}

}
